local ConcetrationGame = {}

GRID_ROWS = 4
GRID_COLS = 5
GRID_TILE_HEIGHT = 62
GRID_TILE_WIDTH = 62
BACK_TILE = 1
EMPTY_TILE = 12
DELAY_TIME = 0.5

--local resourceDefinitions = require "resource_definitions"
--local resourceManager = require "resource_manager"
local resource_definitions = {
  tiles = {
    type = RESOURCE_TYPE_TILED_IMAGE,
    fileName = 'tiles.png',
    tileMapSize = {6,2},
  },
}

  function Game:start ()
    
    self:initialize()
    self.wasClicking = false
    while(true) do
      self:processInput()
      coroutine.yield()
    end
    
  end
  
  function Game:processInput()
    if inputManager:isDown() and not self.wasClicking then
      x,y = inputManager:position()
      worldX, worldY = self.layer:wndToWorld(x, y)
      modelX, modelY = self.tiles.prop:worldToModel(worldX, worldY)
      cellColumn = math.floor(modelX/GRID_TILE_WIDTH) +1 
      cellRow = math.floor(modelY/GRID_TILE_HEIGHT) +1 
      self:choseCell(cellColumn, cellRow)
    end
    self.wasClicking = inputManager:isDown()
  end
  
  function Game:choseCell(column, row)
    if not self.selectedCells[1] then
      if not self:alreadySelectedTile(column, row) then
        self.selectedCells[1] = {column, row}
        self:swapTile(column, row)
      end
    else
      if (self.selectedCells[1][1] == column) and (self.selectedCells[1][2] == row) then
        self.selectedCells[2] = {column, row}
        self:resetTiles()
      else
        if not self:alreadySelectedTile(column, row) then
          self.selectedCells[2] = {column, row}
          self:swapTile(column, row)
          local value1 = self.distributionGrid:getTile(unpack(self.selectedCells[1]))
          local value2 = self.distributionGrid:getTile(unpack(self.selectedCells[2]))
          if (value1 == value2) then
            self:removeTiles()
          else
            self:resetTiles()
          end
        end
      end
    end
  end
  
  function Game:swapTile(column, row)
    local value = self.distributionGrid:getTile(column, row)
    self.tiles.grid:setTile(column, row, value)
  end
  
  function Game:resetTiles()
    sleepCoroutine(DELAY_TIME)
    self.tiles.grid:setTile(
      self.selectedCells[1][1],
      self.selectedCells[1][2],
      BACK_TILE)
    
    self.tiles.grid:setTile(
      self.selectedCells[2][1],
      self.selectedCells[2][2],
      BACK_TILE)
    
    self.selectedCells = {}
  end
  
  function Game:removeTiles()
    sleepCoroutine(DELAY_TIME)
    
    self.tiles.grid:setTile(
      self.selectedCells[1][1],
      self.selectedCells[1][2],
      EMPTY_TILE)
    
    self.tiles.grid:setTile(
      self.selectedCells[2][1],
      self.selectedCells[2][2],
      EMPTY_TILE)
    
    self.selectedCells = {}
  end
  
  
  function Game:alreadySelectedTile(column, row)
    return self.tiles.grid:getTile(column, row) == EMPTY_TILE
  end
  
  function sleepCoroutine(time)
    local timer = MOAITimer.new()
    timer:setSpan(time)
    timer:start()
    MOAICoroutine.blockOnAction(timer)
  end
  
  
  function Game:restartGamePlay() 
    self.distributionGrid = MOAIGrid.new()
    self.distributionGrid:setSize(GRID_COLS, GRID_ROWS)
    local tiles = {
          2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
           7, 7, 8, 8, 9, 9, 10, 10, 11, 11
          }
    
    for x = 1, GRID_COLS, 1 do
      for y = 1, GRID_ROWS, 1 do
        local random = math.random(1, #tiles)
        local value = tiles[random]
        table.remove(tiles, random)
        self.distributionGrid:setTile(x, y, value)
      end
    end
    self.selectedCells = {nil, nil}
  end
  
  
  function Game:initialize ()
    self.layer = MOAILayer2D.new()
    self.layer:setViewport(viewPort)
    MOAIRenderMgr.setRenderTable({ self.layer })
    inputManager:initialize ()
    resourceDefinitions:setDefinitions(resource_definitions)
    self:initializeTiles()
    self:restartGamePlay()
  end
  
  function Game:initializeTiles() 
    local grid = MOAIGrid.new()
    grid:setSize(GRID_COLS, GRID_ROWS, GRID_TILE_WIDTH, GRID_TILE_HEIGHT)
    grid:setRow(1, BACK_TILE, BACK_TILE, BACK_TILE, BACK_TILE, BACK_TILE)
    grid:setRow(2, BACK_TILE, BACK_TILE, BACK_TILE, BACK_TILE, BACK_TILE)
    grid:setRow(3, BACK_TILE, BACK_TILE, BACK_TILE, BACK_TILE, BACK_TILE)
    grid:setRow(4, BACK_TILE, BACK_TILE, BACK_TILE, BACK_TILE, BACK_TILE)
    self.tiles = {}
    self.tiles.grid = grid
    self.tiles.tileset = resourceManager:get('tiles')
    self.tiles.prop = MOAIProp2D.new()
    self.tiles.prop:setDeck(self.tiles.tileset)
    self.tiles.prop:setGrid(self.tiles.grid)
    self.tiles.prop:setLoc(-GRID_COLS/2*GRID_TILE_WIDTH, -GRID_ROWS/2*GRID_TILE_HEIGHT)
    self.layer:insertProp(self.tiles.prop)
  end
  

return ConcetrationGame